%option c++
%option yylineno
%option noyywrap
%option caseless
%{
#include "token.h"
int yylval;
OpType Oper=op_NONE;
DataType Type=dt_NONE;
%}

program					Program{id}({identifier_list});{declarations}{subprogram_declarations}{compound_statement}\.
identifier_list			{id}|{identifier_list}\,{id}
declarations			({declarations}{var}{identifier_list}\:{type}\;)?
type					{standard_type}|{array}\[{num}\.\.{num}\]{of}{standard_type}
standard_type			{integer}|{real}
subprogram_declarations	({subprogram_declarations}{subprogram_declaration}\;)?
subprogram_declaration	{subprogram_head}{declarations}{compount_statement}
subprogram_head			({function}{id}{arguments}\:{standard_type}\;)|({procedure}{id}{arguments}\;)
arguments				(\({parameter_list}\))?
parameter_list			{identifier_list}\:{type}|{parameter_list}\;{identifier_list}\:{type}
compound_statement		{begin}{optional_statements}{end}
optional_statements		({statement_list})?
statement_list			{statement}|statement_list}\;{statement}
statement				({variable}{assignop}{expression})|({procedure_statement})|({compound_statement})|({if}{expression}{then}{statement}{else}{statement})|({while}{expression}{do}{statement})
variable				{id}|({id}\[{expression}\])
procedure_statement		{id}|({id}\({expression_list}\))
expression_list			{expression}|(expression_list\,{expression})
expression				{simple_expression}|({simple_expression}{relop}{simple_expression})
simple_expression		{term}|{sign}{term}|({simple_expression}{addop}{term})
term					{factor}|({term}{mulop}{factor})
factor					{variable}|{id}\({expression_list}\)|{num}|\({expression}\)|{not}{factor}

digit					[0-9]
letter					[A-Za-z]
id						{letter}({letter}|{digit})*
digits					{digit}
int_num					{digits}
optional_fraction		(\.{int_num})?
optional_exponent		(E(\+|\-)?{int_num})?
real_num				{int_num}{optional_fraction}{optional_exponent}


%%

{digit}					{ Oper = op_NONE; Type = dt_DIGIT; return(tc_);}
{letter}				{ Oper = op_NONE; Type = dt_LETTER; return(tc_);}
{id}					{ Oper = op_NONE; Type = dt_ID; return(tc_ID);}
{digits}				{ Oper = op_NONE; Type = dt_REAL; return(tc_NUMBER);}
{int_num}				{ Oper = op_NONE; Type = dt_INT; return(tc_NUMBER);}
{optional_fraction}		{ Oper = op_NONE; Type = dt_FRAC; return(tc_FRAC);}
{optional_exponent}		{ Oper = op_NONE; Type = dt_EXP; return(tc_EXP);}
{real_num}				{ Oper = op_NONE; Type = dt_REAL; return(tc_NUMBER);}

%%